#include<cstdio>//uncle-lu B
#include<cmath>
#include<cstring>
#include<queue>
#include<algorithm>
template<class T>void read(T &x)
{
	x=0;int f=0;char ch=getchar();
	while(ch<'0'||ch>'9') { f|=(ch=='-'); ch=getchar(); }
	while(ch<='9'&&ch>='0') { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
	x = f ? -x : x;
	return ;
}

struct node{
	int v, next;
	double val;
};
node edge[800010];
int head[1010], cnt;
bool visit[1010];
double d[1010];

struct wall{
	int x1, y1, x2, y2;
};
wall line[1010];
int n, m, k;

struct point_node{
	int x, y;
	int wall_cnt;
};
point_node point[1010];
int point_cnt;

struct HeapNode{
	int u;
	double d;
	friend bool operator<(const HeapNode a,const HeapNode b){
		return a.d > b.d;
	}
	HeapNode(int uu,double dd){u = uu;d = dd;}
};
std::priority_queue<HeapNode>qu;

void add_edge(int x, int y)
{
	edge[++cnt].v = y;
	edge[cnt].val = sqrt((double)(point[x].x - point[y].x) * (point[x].x - point[y].x) + (double)(point[x].y - point[y].y) * (point[x].y - point[y].y));
	edge[cnt].next = head[x];
	head[x] = cnt;
	return ;
}

bool intersection(const wall &l1, const wall &l2)
{
    //快速排斥实验
    if ((l1.x1 > l1.x2 ? l1.x1 : l1.x2) < (l2.x1 < l2.x2 ? l2.x1 : l2.x2) ||
        (l1.y1 > l1.y2 ? l1.y1 : l1.y2) < (l2.y1 < l2.y2 ? l2.y1 : l2.y2) ||
        (l2.x1 > l2.x2 ? l2.x1 : l2.x2) < (l1.x1 < l1.x2 ? l1.x1 : l1.x2) ||
        (l2.y1 > l2.y2 ? l2.y1 : l2.y2) < (l1.y1 < l1.y2 ? l1.y1 : l1.y2))
    {
        return false;
    }
    //跨立实验
    if ((((l1.x1 - l2.x1)*(l2.y2 - l2.y1) - (l1.y1 - l2.y1)*(l2.x2 - l2.x1))*
        ((l1.x2 - l2.x1)*(l2.y2 - l2.y1) - (l1.y2 - l2.y1)*(l2.x2 - l2.x1))) > 0 ||
        (((l2.x1 - l1.x1)*(l1.y2 - l1.y1) - (l2.y1 - l1.y1)*(l1.x2 - l1.x1))*
        ((l2.x2 - l1.x1)*(l1.y2 - l1.y1) - (l2.y2 - l1.y1)*(l1.x2 - l1.x1))) > 0)
    {
        return false;
    }
    return true;
}

void dijkstra()
{
	int start = 0;
	for(int i=1;i<=point_cnt;++i)
		d[i] = 1e18;

	HeapNode now(start,0);
	d[start]=0;
	qu.push(now);
	while(!qu.empty())
	{
		now = qu.top();qu.pop();
		if(visit[now.u])continue;
		visit[now.u] = true;
		for(int i=head[now.u];~i;i=edge[i].next)
			if(d[now.u] + edge[i].val < d[edge[i].v])
			{
				d[edge[i].v] = d[now.u] + edge[i].val;
				qu.push((HeapNode){edge[i].v, d[edge[i].v] } );
			}
	}

	return ;
}

int main()
{
	memset(head, -1, sizeof(head));
	read(n);read(m);read(k);

	for (int i = 1; i <= k; i++) 
	{
		read(point[++point_cnt].x); read(point[point_cnt].y);
		point[point_cnt].wall_cnt = i;
		line[i].x1 = point[point_cnt].x; line[i].y1 = point[point_cnt].y;
		read(point[++point_cnt].x); read(point[point_cnt].y);
		point[point_cnt].wall_cnt = i;
		line[i].x2 = point[point_cnt].x; line[i].y2 = point[point_cnt].y;
	}

	read(point[0].x);
	read(point[0].y);	
	read(point[++point_cnt].x);
	read(point[point_cnt].y);
	point[point_cnt].wall_cnt = 0x7f7f7f;

	for(int i=0; i<=point_cnt; ++i)
	{
		for(int j=i+1; j<=point_cnt; ++j)
		{
			if(point[i].wall_cnt == point[j].wall_cnt)
			{
				add_edge(i,j);
				add_edge(j,i);
				continue;
			}
			
			wall now;
			now.x1 = point[i].x; now.y1 = point[i].y;
			now.x2 = point[j].x; now.y2 = point[j].y;

			bool flag = true;
			for(int t = 1; t <= k; ++t)
			{
				if(t == point[i].wall_cnt || t == point[j].wall_cnt)continue;
				
				if(intersection(now, line[t]))
				{
					flag = false;
					break;
				}
			}

			if(flag)
			{
				add_edge(i, j);
				add_edge(j, i);
			}
		}
	}

	dijkstra();

	printf("%.4lf", d[point_cnt]);

	return 0;
}
